#include "Agent.h"
#include "Graph.h"

Agent::Agent(void)
{
}

Agent::Agent(Ogre::SceneManager* pSceneMgr) : mpCurrentAction(0), mpAnimationState(NULL)
{
	setMesh("ninja.mesh", pSceneMgr);
	setScale(Ogre::Vector3(0.25));
	setRotationAxis(Ogre::Vector3::NEGATIVE_UNIT_Z);
	setSpeed(30.0f);
}

Agent::~Agent(void)
{
	while(!mActions.empty())
	{
		delete mActions.front();
		mActions.pop();
	}
}

void Agent::update(const Ogre::FrameEvent& evt)
{
	if(!mpCurrentAction)
		nextAction();

	switch(mpCurrentAction->mType)
	{
	case Action::ACTION_NAVIGATE:
		if(moveToTarget(evt))
		{
			if(!nextWaypoint())
				nextAction();
				
		}
		break;
	default:
		break;
	}

	mpAnimationState->addTime(evt.timeSinceLastFrame);
}

void Agent::nextAction(void)
{
	if(mpCurrentAction != NULL && !mpCurrentAction->mRepeat)
		delete mpCurrentAction;

	//If we run out of actions, repeatedly idle for 1 second
	if(mActions.empty())
		mActions.push(new Action(Action::ACTION_IDLE, 1, NULL, true));

	mpCurrentAction = mActions.front();
	mActions.pop();
	if(mpCurrentAction->mRepeat)
		mActions.push(mpCurrentAction);
	
	onActionChanged();
}

bool Agent::nextWaypoint(void)
{
	if(mPath.empty())
		return false;

	setTarget(mPath.top());
	mPath.pop();
}

void Agent::pushAction(Action::ACTION_TYPE type, float timeout, PathNode* pNode, bool repeat)
{
	mActions.push(new Action(type, timeout, pNode, repeat));
}

void Agent::onActionChanged(void)
{
	switch(mpCurrentAction->mType)
	{
	case Action::ACTION_NAVIGATE:
		{
			PathNode* pNode = mpCurrentAction->mpTarget;
			if(pNode == NULL)
			{
				pNode = Graph::getInstance()->findRandomNode();
			}

			if(Graph::getInstance()->findPath(mpCurrentNode, pNode, &mPath))
			{
				setAnimation("Walk");
				nextWaypoint();
			}
		break;
		}
	case Action::ACTION_IDLE:
	default:
		setAnimation("Idle1");
		break;
	}
}

void Agent::setAnimation(const std::string& animName)
{
	mpAnimationState = mpEntity->getAnimationState(animName);
	mpAnimationState->setLoop(true);
	mpAnimationState->setEnabled(true);
}